/*
 *  Netzpult - Your desk on the web
 *  Copyright (C) 2011  Ulrich Hilger, http://uhilger.de
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/
 */

package de.uhilger.netzpult.client;

import java.util.Iterator;
import java.util.List;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

import de.uhilger.netzpult.shared.UserShare;

/**
 * Dialog zur Freigabe von Dokumenten der Webanwendung netzpult.
 * 
 * @author Copyright (c) Ulrich Hilger, http://uhilger.de
 * @author Published under the terms and conditions of
 * the <a href="http://www.gnu.org/licenses/" target="_blank">GNU General Public License</a>
 */
public class FreigabeDialog extends DialogBox implements ClickHandler, ChangeHandler {
	
	private Button closeBtn;
	private Button applyBtn;
	private Button cancelBtn;
	private RadioButton noRights;
	private RadioButton read;
	private RadioButton readWrite;
	private int docId;
	private OwnerServiceAsync service;
	private List<UserShare> shares;
	private ListBox userList;
	private TextBox userName;
	private static Command resetDetailViewCommand;
	
	public FreigabeDialog(OwnerServiceAsync service, int docId) {
		this.docId = docId;
		this.service = service;
		resetDetailViewCommand = new ResetDetailViewCommand();
		
		setHTML("Dokument freigeben");
		
		userList = new ListBox();
		userList.addChangeHandler(this);
		populateSharesList();
		userList.setVisibleItemCount(10);
		userList.setWidth("180px");
		ScrollPanel sp = new ScrollPanel();
		sp.add(userList);
		
		Label sharesLabel = new Label("berechtigte Benutzer:");
		
		VerticalPanel sharesListPanel = new VerticalPanel();
		sharesListPanel.setSpacing(6);
		sharesListPanel.add(sharesLabel);
		sharesListPanel.add(sp);
		
		applyBtn = new Button("Anwenden");
		applyBtn.addClickHandler(this);
		cancelBtn = new Button("Abbrechen");
		cancelBtn.addClickHandler(this);
		
		HorizontalPanel buttonPanel = new HorizontalPanel();
		buttonPanel.setSpacing(3);
		buttonPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		buttonPanel.add(applyBtn);
		buttonPanel.add(cancelBtn);
		
		Label detailLabel = new Label("Berechtigung fuer Benutzer:");
		userName = new TextBox();
		noRights = new RadioButton("rights", "keine (entfernen)");
		read = new RadioButton("rights", "lesen");
		readWrite = new RadioButton("rights", "lesen und schreiben");
		
		VerticalPanel rightsPanel = new VerticalPanel();
		rightsPanel.setSpacing(6);
		rightsPanel.add(detailLabel);
		rightsPanel.add(userName);
		rightsPanel.add(noRights);
		rightsPanel.add(read);
		rightsPanel.add(readWrite);
		rightsPanel.add(buttonPanel);

		HorizontalPanel userPanel = new HorizontalPanel();
		userPanel.add(sharesListPanel);
		userPanel.add(rightsPanel);
		closeBtn = new Button("Schliessen");
		closeBtn.addClickHandler(this);

		VerticalPanel mainPanel = new VerticalPanel();
		mainPanel.setSpacing(6);
		mainPanel.add(userPanel);
		mainPanel.add(closeBtn);
		add(mainPanel);
	}
	
	private void populateSharesList() {
		service.getUserShares(docId, new AsyncCallback<List<UserShare>>(){

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("FreigabeDialog Fehler im Serveraufruf: " + caught.getMessage());
			}

			@Override
			public void onSuccess(List<UserShare> result) {
				shares = result;
				userList.clear();
				Iterator<UserShare> i = shares.iterator();
				while(i.hasNext()) {
					userList.addItem(i.next().getUserId());
				}		
			}
		});
	}
	
	private void populateDetailView(UserShare share) {
		userName.setText(share.getUserId());
		userName.setEnabled(false);
		switch(share.getRights()) {
		case UserShare.NONE:
			break;
		case UserShare.READ:
			read.setValue(true);
			break;
		case UserShare.READ_WRITE:
			readWrite.setValue(true);
			break;
		}
	}
	
	private class ResetDetailViewCommand implements Command {

		@Override
		public void execute() {
			userName.setEnabled(true);
			userName.setText("");
			read.setValue(true);
			int index = userList.getSelectedIndex();
			if(index > -1) {
				userList.setItemSelected(index, false);
			}
		}
		
	}

	@Override
	public void onClick(ClickEvent event) {
		Object obj = event.getSource();
		if(obj.equals(closeBtn)) {
			hide();
		} else if(obj.equals(applyBtn)) {
			UserShare share = new UserShare();
			share.setDocId(docId);
			share.setUserId(userName.getText());
			if(read.getValue()) {
				share.setRights(UserShare.READ);
				saveShare(share);
			} else if(readWrite.getValue()) {
				share.setRights(UserShare.READ_WRITE);
				saveShare(share);
			} else {
				service.deleteUserShare(share, new RemoveCallback(shares, userList));
			}
		} else if(obj.equals(cancelBtn)) {
			resetDetailViewCommand.execute();
		}
	}
	
	private void saveShare(UserShare share) {
		if(userName.isEnabled()) {
			service.addUserShare(share, new UpdateCallback(shares, userList));
		} else {
			service.updateUserShare(share, new UpdateCallback(shares, userList));
		}
	}
	
	private static class RemoveCallback implements AsyncCallback<UserShare> {
		
		private List<UserShare> myUserShares;
		private ListBox myUserList;
		
		public RemoveCallback(List<UserShare> list, ListBox listBox) {
			super();
			this.myUserShares = list;
			this.myUserList = listBox;
		}

		@Override
		public void onFailure(Throwable caught) {
			resetDetailViewCommand.execute();
			Window.alert("FreigabeDialog Fehler im Serveraufruf: " + caught.getMessage());
		}

		@Override
		public void onSuccess(UserShare result) {
			int index = myUserShares.indexOf(result);
			if(index > -1) {
				myUserShares.remove(index);
				myUserList.removeItem(index);
			}
			resetDetailViewCommand.execute();
		}
		
	}

	private static class UpdateCallback implements AsyncCallback<UserShare> {
		
		private List<UserShare> myUserShares;
		private ListBox myUserList;
		
		public UpdateCallback(List<UserShare> list, ListBox listBox) {
			super();
			this.myUserShares = list;
			this.myUserList = listBox;
		}

		@Override
		public void onFailure(Throwable caught) {
			resetDetailViewCommand.execute();
			Window.alert("FreigabeDialog Fehler im Serveraufruf: " + caught.getMessage());
		}

		@Override
		public void onSuccess(UserShare result) {
			int index = myUserShares.indexOf(result);
			if(index > -1) {
				myUserShares.set(index, result);
				myUserList.setItemText(index, result.getUserId());
			} else {
				myUserShares.add(result);
				myUserList.addItem(result.getUserId());
			}
			resetDetailViewCommand.execute();
		}
		
	}

	@Override
	public void onChange(ChangeEvent event) {
		Object src = event.getSource();
		if(src.equals(userList)) {
			int index = userList.getSelectedIndex();
			if(index > -1) {
				populateDetailView(shares.get(index));
			}
		}
		
	}

}
